<script setup>
import MyNav from "../../../components/MyNav.vue";
import {onMounted, ref} from "vue";
import {ElMessage} from "element-plus";
import {getResponseData} from "../../../util/request.js";
import {listMenuIdsApi, updateMenusApi} from "../../../api/ums/role.js";
import {isNotNull} from "../../../util/index.js";
import {simpleListApi} from "../../../api/axios.js";

// 获取当前角色主键和角色标题
let roleId = sessionStorage.getItem('roleId');
let roleTitle = sessionStorage.getItem('roleTitle');

/* ==================== 页面常量 ==================== */

// 路径导航
const navItems = [
  {icon: 'User', label: '用户管理'},
  {icon: 'Avatar', label: '角色列表', url: '/Role'},
  {icon: 'UserFilled', label: '（' + roleTitle + '）的菜单列表'},
];

/* ==================== 查询角色菜单 ==================== */

// 当前角色拥有的全部菜单列表 + 组件ElTransfer需要的key数组
let myMenuIds = ref([]);

/** 查询指定角色的全部菜单ID列表 */
async function listMyMenuIds() {
  let data = getResponseData(await listMenuIdsApi(roleId));
  if (isNotNull(data)) {
    myMenuIds.value = data;
  }
}

/* ==================== 查询全部菜单 ==================== */

let allMenus = ref([]);

// 用于记录菜单的父子关系，以备修改菜单时使用
let menuRelations = {};

/** 查询全部菜单列表并组装为ElTransfer需要的格式 */
async function listMenus() {
  let data = getResponseData(await simpleListApi(null, {module: 'menu'}));
  if (isNotNull(data)) {
    for (let i in data) {
      // 记录菜单的父子关系 [{id: pid}, {id: pid} ..]
      menuRelations[data[i]['id']] = data[i]['pid'];
      // 组装 ElTransfer 数据
      if (data[i]['pid'] !== 0) {
        let label = `${data[i]['parentTitle']} / ${data[i]['title']}`;
        allMenus.value.push({key: data[i]['id'], label: label});
      }
    }
  }
}

/* ==================== 确认修改角色的菜单 ==================== */

/**
 * 处理选中的菜单ID列表
 *
 * 1. 遍历处理选中的菜单ID列表。
 * 2. 将选中的菜单ID追加到临时数组 result 中。
 * 3. 根据菜单的父子关系 menuRelations 获取该菜单的父菜单ID。
 * 4. 若临时数组 result 中已存在相同的父菜单ID，则不会重复追加。
 * 5. 若临时数组 result 中不存在相同的父菜单ID，则追加到临时数组 result 中。
 *
 * @param menuIds 选中的菜单列表
 * @return result 处理后的菜单ID列表，包括全部子菜单的ID和对应父菜单的ID，不存在重复项。
 */
function buildMenuIds(menuIds) {
  let result = [];
  for (let i in menuIds) {
    result.push(menuIds[i]);
    let parentMenuId = menuRelations[menuIds[i]];
    if (result.indexOf(parentMenuId) === -1) {
      result.push(parentMenuId);
    }
  }
  return result;
}

/** 修改当前角色的菜单列表 */
async function updateMyMenus() {
  let data = getResponseData(await updateMenusApi({
    id: roleId,
    menuIds: buildMenuIds(myMenuIds.value)
  }));
  if (isNotNull(data)) {
    ElMessage.success('菜单列表更新成功！');
  }
}

/* ==================== 加载函数 ==================== */

onMounted(() => {
  listMenus();
  listMyMenuIds();
});

</script>

<template>
  <div class="role-menus-body">
    <my-nav :items="navItems"/>
    <el-divider/>
    <el-transfer v-if="allMenus"
                 v-model="myMenuIds"
                 :data="allMenus"
                 filterable
                 filter-placeholder="输入菜单名称"
                 :titles="['全部可选菜单', '当前已选菜单']"
                 :props="{key: 'key', label: 'label'}"
                 :button-texts="['移除', '添加']"
                 @change="updateMyMenus"/>
  </div>
</template>

<style scoped lang="scss">
.role-menus-body {
  text-align: center; // 内容居中


  .update-menus-btn {
    margin-top: 20px; // 上外边距
    width: 87%; // 宽度
  }
}

/* 修改EL穿梭框高度 */
:deep(.el-transfer-panel), :deep(.el-transfer-panel__body) {
  width: 400px; // 宽度
  height: 580px; // 高度
}
</style>